﻿using System;
using System.Linq;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Unity;
using IQToolkit;
using IQToolkit.Data;
using IQToolkit.Data.Mapping;
using IQToolkit.Data.MySqlClient;
using Data;
using Data.MySql;
using Infrastucture;
using Infrastucture.Factories;
using TimeSplicerModule.Factories;
using TimeSplicerModule.Controllers;
using TimeSplicerModule.Services;
using TimeSplicerModule.Services.DeveloperServices;
using TimeSplicerModule.Security;

namespace TimeSplicerModule
{
    public class TimeSplicerModule : IModule
    {
        private readonly IRegionManager _regionManager;
        private readonly IUnityContainer _container;

        public TimeSplicerModule(IRegionManager regionManager, IUnityContainer container)
        {
            _regionManager = regionManager;
            _container = container;
        }

        

        public void Initialize()
        {
            // set up db provider
            // TODO: create the connection string
            string conn = "SERVER=127.0.0.1;DATABASE=timesplicer;UID=Rudy;PASSWORD=admin;";

            //var provider = DbEntityProvider.From("IQToolkit.Data.MySqlClient", conn, "TimeSplicerModule.Data2.MySqlData"); // Looks like i need to do the mappting
            //var provider = DbEntityProvider.From(typeof(IQToolkit.Data.MySqlClient.MySqlQueryProvider),  )
            //IQToolkit.Data.Common.QueryPolicy pol = new IQToolkit.Data.Common.QueryPolicy();
            //var provider =  //DbEntityProvider.From(typeof(IQToolkit.Data.MySqlClient.MySqlQueryProvider), conn, "TimeSplicerModule.Data2.MySqlData", pol);
            //var provider = IQToolkit.Data.MySqlClient.MySqlQueryProvider.From(conn, "TimeSplicerModule.Data2.MySqlData");

            var provider = DbEntityProvider.From("IQToolkit.Data.MySqlClient", conn, "TimeSplicerModule.Database.Timesplicer");

           // provider.Connection.Open();
            var db = new Database.Timesplicer(provider);
         
            
            //var p = db.Priorities.FirstOrDefault(x => x.Name == "High");
            //db.Priorities.InsertOrUpdate(p);
         
           

            // register views
            _container.RegisterType<Object, Views.LoginView>(typeof(Views.LoginView).Name);
            _container.RegisterType<Object, Views.StatusListView>(typeof(Views.StatusListView).Name);
            _container.RegisterType<Object, Views.PriorityListView>(typeof(Views.PriorityListView).Name);
            _container.RegisterType<Object, Views.PriorityView>(typeof(Views.PriorityView).Name);
            _container.RegisterType<Object, Views.CategoryListView>(typeof(Views.CategoryListView).Name);
            _container.RegisterType<Object, Views.CategoryView>(typeof(Views.CategoryView).Name);
            _container.RegisterType<Object, Views.TeamListView>(typeof(Views.TeamListView).Name);
            _container.RegisterType<Object, Views.TeamView>(typeof(Views.TeamView).Name);
            _container.RegisterType<Object, Views.JobRoleListView>(typeof(Views.JobRoleListView).Name);
            _container.RegisterType<Object, Views.JobRoleView>(typeof(Views.JobRoleView).Name);
            _container.RegisterType<Object, Views.ApplicationRoleListView>(typeof(Views.ApplicationRoleListView).Name);
            _container.RegisterType<Object, Views.ApplicationRoleView>(typeof(Views.ApplicationRoleView).Name);
            _container.RegisterType<Object, Views.ProjectRoleListView>(typeof(Views.ProjectRoleListView).Name);
            _container.RegisterType<Object, Views.ProjectRoleView>(typeof(Views.ProjectRoleView).Name);
            _container.RegisterType<Object, Views.UserListView>(typeof(Views.UserListView).Name);
            _container.RegisterType<Object, Views.UserView>(typeof(Views.UserView).Name);
            _container.RegisterType<Object, Views.ProjectListView>(typeof(Views.ProjectListView).Name);
            _container.RegisterType<Object, Views.ProjectView>(typeof(Views.ProjectView).Name);
            _container.RegisterType<Object, Views.TaskView>(typeof(Views.TaskView).Name);
            _container.RegisterType<Object, Views.TaskListView>(typeof(Views.TaskListView).Name);
            _container.RegisterType<Object, Views.ServicesView>(typeof(Views.ServicesView).Name);
            


            // todo: register controllers - probably have to do this in the bootstrapper
            _container.RegisterInstance<ILoginController>(new LoginController());
            _container.RegisterInstance<ITeamController>(new TeamController());
            _container.RegisterInstance<IStatusController>(new StatusController());
            _container.RegisterInstance<ICategoryController>(new CategoryController());
            _container.RegisterInstance<IApplicationRoleController>(new ApplicationRoleController());
            _container.RegisterInstance<IJobRoleController>(new JobRoleController());
            _container.RegisterInstance<IUserController>(new UserController());
            _container.RegisterInstance<IProjectController>(new ProjectController());
            _container.RegisterInstance<IProjectRoleController>(new ProjectRoleController());
            _container.RegisterInstance<IPriorityController>(new PriorityController());
            _container.RegisterInstance<ITaskController>(new TaskController());
            



            // factory reistragion
            // TODO: Changing to new factory method to point to MySQL
            var priorityFactory = new PriorityFactory(provider, db.Priorities);
            var statusFactory = new StatusFactory(provider, db.Statuses);
            var applicationItemFactory = new ApplicationItemFactory(provider, db.ApplicationItems);
            var applicationPermissionFactory = new ApplicationPermissionFactory(provider, db.ApplicationPermissions);


            // move thise over next
            var applicationRoleFactory = new ApplicationRoleFactory(provider, db.ApplicationRoles);
            var applicationRolePermissionsFactory = new ApplicationRolePermissionFactory(provider, db.ApplicationRolePermissions);
            var teamFactory = new TeamFactory(provider, db.Teams);
            var userFactory = new UserFactory(provider, db.Users);

            // then these, will need to test these
            var categoryFactory = new CategoryFactory(provider, db.Categories);
            var teamCategoryFactory = new TeamCategoryFactory(provider, db.TeamCategories);
            var timestampFactory = new TimestampFactory(provider, db.Timestamps);
            var taskFactory = new TaskFactory(provider, db.Tasks);
            var projectFactory = new ProjectFactory(provider, db.Projects);
            var projectRoleFactory = new ProjectRoleFactory(provider, db.ProjectRoles);
            var projectUserFactory = new ProjectUserFactory(provider, db.ProjectUsers);
            var taskSchedulerFactory = new TaskScheduleFactory(provider, db.TaskSchedules);
            var scheduledTaskFactory = new ScheduledTaskFactory(provider, db.ScheduledTasks);



            _container.RegisterInstance<IApplicationItemFactory>(applicationItemFactory);
            _container.RegisterInstance<IApplicationPermissionFactory>(applicationPermissionFactory);
            _container.RegisterInstance<IStatusFactory>(statusFactory);
            _container.RegisterInstance<IPriorityFactory>(priorityFactory);

            _container.RegisterInstance<IApplicationRoleFactory>(applicationRoleFactory);
            _container.RegisterInstance<IApplicationRolePermissionFactory>(applicationRolePermissionsFactory);
            _container.RegisterInstance<ITeamFactory>(teamFactory);
            _container.RegisterInstance<IUserFactory>(userFactory);

            _container.RegisterInstance<ICategoryFactory>(categoryFactory);
            _container.RegisterInstance<ITeamCategoryFactory>(teamCategoryFactory);
            _container.RegisterInstance<ITimestampFactory>(timestampFactory);
            _container.RegisterInstance<ITaskFactory>(taskFactory);
            _container.RegisterInstance<IProjectFactory>(projectFactory);
            _container.RegisterInstance<IProjectRoleFactory>(projectRoleFactory);
            _container.RegisterInstance<IProjectUserFactory>(projectUserFactory);
            _container.RegisterInstance<ITaskScheduleFactory>(taskSchedulerFactory);
            _container.RegisterInstance<IScheduledTaskFactory>(scheduledTaskFactory);



            // register services
            var applicationRoleService = new ApplicationRoleService(_container, applicationRoleFactory, applicationItemFactory, applicationPermissionFactory,
                applicationRolePermissionsFactory);
            var projectRoleService = new ProjectRoleService(_container, projectRoleFactory, applicationPermissionFactory);
            var teamService = new TeamService(_container, teamFactory);
            var categoryService = new CategoryService(_container, categoryFactory, teamService, teamCategoryFactory);
            var userService = new UserService(_container, userFactory, teamService, teamFactory, applicationRoleFactory, applicationRoleService, statusFactory);
            var projectService = new ProjectService(_container, projectFactory, categoryService, categoryFactory, 
                priorityFactory, statusFactory, userService, userFactory, projectRoleFactory, projectUserFactory, taskFactory, timestampFactory);
            var timestampService = new TimestampService(_container, timestampFactory, projectFactory, taskFactory);
            var reportsService = new ReportsService(projectService, categoryFactory);
            var taskScheduleService = new TaskScheduleService(taskSchedulerFactory, scheduledTaskFactory);
            var taskService = new TaskService(_container, userService, projectService, timestampService, taskFactory, priorityFactory, categoryService, categoryFactory, statusFactory,
                projectUserFactory, userFactory, projectRoleFactory, taskSchedulerFactory, taskScheduleService);
            var scheduingService = new SchedulingService(taskFactory, taskService, taskSchedulerFactory, scheduledTaskFactory, statusFactory);



            _container.RegisterInstance<IApplicationRoleService>(applicationRoleService);
            _container.RegisterInstance<IProjectRoleService>(projectRoleService);
            _container.RegisterInstance<ITeamService>(teamService);
            _container.RegisterInstance<ICategoryService>(categoryService);
            _container.RegisterInstance<IUserService>(userService);
            _container.RegisterInstance<IProjectService>(projectService);
            // need to move tasks servie up
            _container.RegisterInstance<ITaskService>(taskService);
            _container.RegisterInstance<ITimestampService>(timestampService);
            _container.RegisterInstance<IReportsService>(reportsService);
            _container.RegisterInstance<ITaskScheduleService>(taskScheduleService);
            _container.RegisterInstance<ISchedulingService>(scheduingService);





            // register session service
            _container.RegisterInstance<ISessionService>(new SessionService(userFactory, applicationItemFactory, applicationPermissionFactory, applicationRoleFactory, applicationRolePermissionsFactory, priorityFactory, statusFactory));
            _container.RegisterInstance<ISession>(new Session());
            // may need to create user here then 


            // may need to drop and rebuild
        }
    }
}
